﻿namespace FFF.Test.DataAccess.Framework.Configuration
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Claims;
    using System.Text;
    using Abp.Dependency;
    using Microsoft.AspNetCore.Http;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.ChangeTracking;
    using Microsoft.EntityFrameworkCore.Metadata;
    using Newtonsoft.Json;
    using FFF.Test.Entity.Demo;
    using FFF.Test.Entity.Demo.View;
    using FFF.Test.Entity.FW.View;
    using FFF.Test.Util.Consts;
    using Ydm.Extensions;

    /// <summary>
    /// 数据保持帮助类
    /// </summary>
    public static class DbSaveConfiguration
    {
        /// <summary>
        /// 数据保存前的数据初始化
        /// </summary>
        /// <param name="entries">实体集合</param>
        /// <param name="iocResolver">依赖注入容器</param>
        public static void BeforeSaveInitData(IEnumerable<EntityEntry> entries, IIocResolver iocResolver)
        {
            foreach (var entity in entries.Where(x => x.State == EntityState.Added || x.State == EntityState.Modified))
            {
                var props = entity.Metadata.GetProperties();
                foreach (var prop in props)
                {
                    if (entity.State == EntityState.Added && prop.Name == "CreateTime")
                    {
                        entity.CurrentValues["CreateTime"] = DateTime.Now;
                    }

                    if (entity.State == EntityState.Added && prop.Name == "CreateTime")
                    {
                        entity.CurrentValues["CreateTime"] = DateTime.Now;
                    }

                    if (entity.State == EntityState.Added && prop.Name == "IsDeleted")
                    {
                        entity.CurrentValues["IsDeleted"] = (byte)0;
                    }

                    var httpContext = iocResolver.Resolve<IHttpContextAccessor>().HttpContext;

                    // 获取用户的登录信息
                    if (httpContext != null)
                    {
                        // 设置公司的全局过滤
                        HeadBuInfo buHeader = null;
                        string buInfoStr = httpContext.User.Claims.FirstOrDefault(d => d.Type == ClaimTypes.Webpage)?.Value;
                        if (buInfoStr != null)
                        {
                            buHeader = JsonConvert.DeserializeObject<HeadBuInfo>(buInfoStr);
                        }

                        if (buHeader != null)
                        {
                            if (entity.State == EntityState.Added && prop.Name == "BuUnitGUID")
                            {
                                var buid = entity.CurrentValues["BuUnitGUID"];
                                if (buid == null)
                                {
                                    entity.CurrentValues["BuUnitGUID"] = buHeader.BuGUID;
                                }
                            }

                            var tenantId = entity.CurrentValues["TenantId"];
                            if (buHeader.CompanyGUID != null && tenantId == null)
                            {
                                entity.CurrentValues["TenantId"] = buHeader.CompanyGUID;
                            }
                        }

                        if (httpContext.Session.GetUserInfo() is ViewFWUser userInfo)
                        {
                            if (entity.State == EntityState.Added && prop.Name == "CreateGUID")
                            {
                                entity.CurrentValues["CreateGUID"] = userInfo.Id;
                            }

                            if (entity.State == EntityState.Added && prop.Name == "CreatedName")
                            {
                                entity.CurrentValues["CreatedName"] = userInfo.UserName;
                            }

                            if (entity.State == EntityState.Added && prop.Name == "TenantId")
                            {
                                var tenantId = entity.CurrentValues["TenantId"];
                                if (tenantId == null)
                                {
                                    entity.CurrentValues["TenantId"] = userInfo.TenantId;
                                }
                            }

                            if (entity.State == EntityState.Modified && prop.Name == "ModifiedGUID")
                            {
                                entity.CurrentValues["ModifiedGUID"] = userInfo.Id;
                            }

                            if (entity.State == EntityState.Modified && prop.Name == "ModifiedName")
                            {
                                entity.CurrentValues["ModifiedName"] = userInfo.UserName;
                            }
                        }

                        // 记录最后一次更改人的IP地址
                        var createIp = httpContext.Request.Headers["X-Real-IP"].FirstOrDefault();

                        var token = httpContext.Request.Headers["Authorization"].FirstOrDefault();
                        if (!token.IsNullOrEmpty())
                        {
                            createIp = createIp + token.Substring(token.Length - 20, 20);
                        }

                        if (!createIp.IsNullOrEmpty())
                        {
                            if (entity.State == EntityState.Added && prop.Name == "CreateDesc")
                            {
                                var approveGUID = entity.CurrentValues["CreateDesc"];
                                if (approveGUID == null)
                                {
                                    entity.CurrentValues["CreateDesc"] = createIp;
                                }
                            }

                            if ((entity.State == EntityState.Modified) && prop.Name == "ModifiedDesc")
                            {
                                var approveState = entity.CurrentValues["ModifiedDesc"];
                                if (approveState == null)
                                {
                                    entity.CurrentValues["ModifiedDesc"] = createIp;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
